import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public class Spider extends UnicastRemoteObject implements SpiderInterface {
	private static final long serialVersionUID = -7192370819962471594L;
	private Queue<String> queue;
	private ArrayList<String> links;
	private ArrayList<String> mails;
	private ArrayList<String> visited;

	public Spider() throws RemoteException {
		queue = new LinkedList<String>();
		links = new ArrayList<String>();
		mails = new ArrayList<String>();
		visited = new ArrayList<String>();
	}

	public synchronized void startCrawling() {
		queue.clear();
		new Processor(this).start();
	}

	public synchronized ArrayList<Collection<String>> fetch() {
		ArrayList<Collection<String>> oldLists = new ArrayList<Collection<String>>();
		oldLists.add(visited);
		oldLists.add(queue);
		oldLists.add(links);
		oldLists.add(mails);
		return oldLists;
	}

	public synchronized ArrayList<Collection<String>> fetchAndSet(
			ArrayList<String> newVisited, Queue<String> newQueue,
			ArrayList<String> newLinks, ArrayList<String> newMails) {
		ArrayList<Collection<String>> oldLists = new ArrayList<Collection<String>>();
		oldLists.add(visited);
		oldLists.add(queue);
		oldLists.add(links);
		oldLists.add(mails);
		Iterator<String> itr = newQueue.iterator();
		while (itr.hasNext()) {
			if (visited.contains(itr.next())) {
				itr.remove();
			}
		}
		visited = newVisited;
		queue = newQueue;
		links = newLinks;
		mails = newMails;
		notifyAll();
		return oldLists;
	}

	public synchronized void addLink(URL url) {
		if (isEmail(url)) {
			if (!mails.contains(url.toString())) {
				mails.add(url.toString());
			}
		} else {
			if (!links.contains(url.toString())) {
				links.add(url.toString());
				queue.add(url.toString());
			}
		}
		notifyAll();
	}

	public synchronized Collection<String> getLinks() {
		return links;
	}

	public synchronized Collection<String> getMails() {
		return mails;
	}

	public synchronized URL getURL() {
		while (queue.isEmpty()) {
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		String u = queue.poll();
		visited.add(u);
		try {
			return new URL(u);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	private boolean isEmail(URL url) {
		if (url.toString().startsWith("mailto:")) {
			return true;
		}
		return false;
	}

}